#include "regx52.h"

// 数码管显示的数字数组
// 默认值为10（表示空白），数组的索引和数码管位置一一对应
// LED_Num[0] 未使用，方便后续与数码管位置直接对应
unsigned char LED_Num[9] = {0, 10, 10, 10, 10, 10, 10, 10, 10};

// 数码管显示编码数组
// 数组内容：0~9 对应的数码管段码编码，最后一个 0x00 表示空白
unsigned char code arr[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x00};

/**
 * @brief 设置指定数码管显示的数字
 * @param A 数码管位置 (1~8)
 * @param B 显示的数字 (0~9) 或空白 (10)
 */
void LED_put(unsigned char A, unsigned char B)
{
    LED_Num[A] = B; // 设置指定位置的数码管显示内容
}

/**
 * @brief 控制数码管显示
 * @param A 数码管位置 (1~8)
 * @param B 显示的数字 (0~9) 或空白 (10)
 * @note 此函数会通过 P2_4, P2_3, P2_2 控制数码管的位选，通过 P0 输出段选
 */
void LED(unsigned char A, unsigned char B)
{
    P0 = 0; // 清除段选，避免闪烁

    // 位选控制，根据位置 A 激活相应的数码管
    switch (A)
    {
        case 1: P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
        case 2: P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
        case 3: P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
        case 4: P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
        case 5: P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
        case 6: P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
        case 7: P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
        case 8: P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
    }

    // 段选控制，输出对应数字的编码
    P0 = arr[B];
    // 不需要延时，因为定时器会自动实现切换频率
}

/**
 * @brief 数码管扫描函数
 *        定时调用此函数实现动态扫描显示
 */
void LED_put_Scan()
{
    static unsigned char i = 0; // 当前扫描的数码管位置

    i++; // 切换到下一个数码管
    LED(i, LED_Num[i]); // 更新显示内容
    if (i == 8) i = 0;  // 如果到达最后一个数码管，重置为第一个
}

/**
 * @brief 定时中断函数，用于实现数码管动态扫描
 *        每次中断调用 LED_put_Scan
 */
// void Timer_Cut() interrupt 1
// {
//     static unsigned int LED_Count = 0; // 定义计数变量

//     TL0 = 0x66; // 设置定时初值（低字节）
//     TH0 = 0xFC; // 设置定时初值（高字节）

//     LED_Count++; // 每次中断计数加 1

//     if (LED_Count == 1) // 调节扫描频率
//     {
//         LED_Count = 0; // 计数清零
//         LED_put_Scan(); // 调用数码管扫描函数
//     }
// }
